package com.airy.apprepairequipment.socket;

import com.airy.apprepairequipment.common.util.ByteUtil;
import com.airy.apprepairequipment.common.util.CRCUtil;
import com.airy.apprepairequipment.entity.RtJdloopgroupEntity;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

/**
 * @description: 服务端客户消息处理线程类
 * @author airy
 * @date 2020/11/19 8:34
 */

/**
 * 三：处理客户端请求数据，一台服务器要面对成千上万的客户连接，如果采用串行方式收到一个请求就调用主线程处理
 * 那么其他的客户端就被迫等待。针对这种情况，，服务端客户消息的处理应该采用并行方式，
 * 即new出每一个客户消息工作线程，在不同的线程中处理客户请求的数据。
 * 服务端客户连接处理：
 * 服务端主线程不断地轮询客户端连接，一个客户发起连接，服务端就为客户端创建一个服务端消息处理线程
 * 服务端客户消息处理：
 * 针对一个Socket，不断轮询传输过来的byte流，比如客户可能5秒发一次消息，那么服务端客户消息处理线程就应该接收到5秒一次的消息
 */
public class SocketServerClientHandler extends Thread {

    //每个消息通过Socket进行传输
    private Socket clientConnectSocket;
    //fstrDeviceid
    private String fstrDeviceid;
    //交调的访问路径
    private String jiaodiaoUrl;
    //微波的访问路径
    private String weiboUrl;

    @Autowired
    public SocketServerClientHandler(Socket clientConnectSocket, String fstrDeviceid, String jiaodiaoUrl, String weiboUrl) {
        this.clientConnectSocket = clientConnectSocket;
        this.fstrDeviceid = fstrDeviceid;
        this.jiaodiaoUrl = jiaodiaoUrl;
        this.weiboUrl = weiboUrl;
    }

    //synchronized 关键字
    //由于java的每个对象都有一个内置锁，当用此关键字修饰方法时，
    //内置锁会保护整个方法。在调用该方法前，需要获得内置锁，否则就处于阻塞状态。
    @Override
    public synchronized void run() {

        try {
            InputStream inputStream = clientConnectSocket.getInputStream();//获取客户端发送的流
            System.out.println("客户端传输的流：" + inputStream);
            SocketAddress remoteSocketAddress = clientConnectSocket.getRemoteSocketAddress();//远程主机地址
            System.out.println("远程主机地址：" + remoteSocketAddress);
            int port = clientConnectSocket.getPort();
            System.out.println("远程主机端口号：" + port);
            System.out.println("fstrDeviceid：" + fstrDeviceid);
            System.out.println("jiaodiaoUrl：" + jiaodiaoUrl);
            System.out.println("weiboUrl：" + weiboUrl);

            byte[] data = new byte[512];
            while (inputStream.read(data) != -1) {

                //转为16进制
                String string = ByteUtil.BinaryToHexString(data);
                String message = string.substring(string.indexOf("AA AA"), string.indexOf("EE EE") + 5);

                System.out.println("客户端传来消息: " + message);

                //将传过来的数据根据" "进行分割为字符串数组
                String[] s = message.split(" ");

                int sum = 0;
                //遍历数组，得到每一个字节，转为十进制进行求和计算
                for (int i = 0; i < s.length; i++) {
                    sum += Integer.parseInt(s[i], 16);
                }

                //DSC 反馈交互 02 包
                if ("AA".equals(s[0]) && "AA".equals(s[1]) && Integer.parseInt(s[2], 16) == 18) {
                    //DSC->RD
                    String sbm = "";
                    for (int i = 5; i <= 20; i++) {
                        sbm = sbm + " " + s[i];
                    }

                    OutputStream out = clientConnectSocket.getOutputStream();//输出流
                    out.write(("AA AA 12 00 02" + sbm + " 02 D8 B5 EE EE").getBytes());
                    System.out.println("DSC 回复 RD 发送的站点信息 02 包的内容:" + "AA AA 12 00 02" + sbm + " 02 D8 B5 EE EE");
                }

                //激光交调精简协议1类
                if ("AA".equals(s[0]) && "AA".equals(s[1]) && Integer.parseInt(s[4], 16) == 1) {

                    //创建RT对象集合
                    Map<Integer, RtJdloopgroupEntity> hashMap = new HashMap<>();

                    System.out.println("激光交调精简协议1类");
                    //RD->DSC
                    //包长
                    System.out.println("包长：" + (Integer.parseInt((s[3]) + (s[2]), 16)));
                    //数据包类型
                    System.out.println("数据包类型：" + Integer.parseInt(s[4], 16));
                    //设备身份识别码
                    String hex1 = "";
                    for (int i = 5; i <= 20; i++) {
                        hex1 += s[i];
                    }
                    System.out.println("设备身份识别码:" + convertHexToString(hex1));

                    //站点编号
                    String hex2 = "";
                    for (int i = 21; i <= 35; i++) {
                        hex2 += s[i];
                    }
                    System.out.println("站点编号:" + convertHexToString(hex2));

                    //设备硬件错误码
                    if (Integer.parseInt(s[36], 16) == 0) {
                        System.out.println("设备硬件错误码:" + "00");
                    } else {
                        System.out.println("设备硬件错误码:" + Integer.parseInt(s[36], 16));
                    }
                    //调查内容
                    System.out.println("调查内容:" + Integer.parseInt(s[37], 16));
                    //年月日
                    int year = Integer.parseInt((s[39] + s[38]), 16);
                    int month = Integer.parseInt(s[40], 16);
                    int day = Integer.parseInt(s[41], 16);
                    Calendar now = Calendar.getInstance();
                    int hour = now.get(Calendar.HOUR_OF_DAY);
                    int minute = now.get(Calendar.MINUTE);
                    int second = now.get(Calendar.SECOND);
                    String dates = year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
                    System.out.println("时间：" + dates);

                    //交通数据周期
                    System.out.println("交通数据周期:" + Integer.parseInt(s[42], 16) + "分钟");
                    //时间序号
                    int l = Integer.parseInt(s[44], 16) + Integer.parseInt(s[43], 16);
                    System.out.println("时间序号:" + l);
                    //车道数
                    int m = Integer.parseInt(s[45], 16);
                    System.out.println("车道数:" + ("0" + m));

                    //对各个车道进行遍历
                    for (int i = 1; i <= m; i++) {

                        RtJdloopgroupEntity allEntity = new RtJdloopgroupEntity();
                        allEntity.setFdtTime(dates);

                        int a = 46;
                        a += (i - 1) * 32;

                        //车道号46
                        int num = Integer.parseInt(s[a], 16);
                        System.out.println("车道号：" + num);
                        //跟车百分比47
                        System.out.println("跟车百分比：" + Integer.parseInt(s[a + 1], 16));
                        //平均车头间距48,49
                        BigDecimal p = BigDecimal.valueOf(Integer.parseInt(s[a + 3] + s[a + 2], 16));
                        System.out.println("平均车头间距：" + p);
                        allEntity.setFintVh(p);
                        //时间占有率50
                        BigDecimal occupy = BigDecimal.valueOf(Integer.parseInt(s[a + 4], 16));
                        System.out.println("时间占有率：" + occupy);
                        allEntity.setFintOccupy(occupy);
                        //中小客车交通流量51,52
                        BigDecimal zhongxiao = BigDecimal.valueOf(Integer.parseInt(s[a + 6] + s[a + 5], 16));
                        System.out.println("中小客车交通流量：" + zhongxiao);
                        allEntity.setFintV1(zhongxiao);
                        //中小客车平均地点车速53
                        BigDecimal zhongxiaosudu = BigDecimal.valueOf(Integer.parseInt(s[a + 7], 16));
                        System.out.println("中小客车平均地点车速：" + zhongxiaosudu);
                        allEntity.setFintS1(zhongxiaosudu);
                        //小型货车交通流量54,55
                        BigDecimal xiaoxing = BigDecimal.valueOf(Integer.parseInt(s[a + 9] + s[a + 8], 16));
                        System.out.println("小型货车交通流量：" + xiaoxing);
                        allEntity.setFintV2(xiaoxing);
                        //小型货车平均地点车速56
                        BigDecimal xiaoxingsudu = BigDecimal.valueOf(Integer.parseInt(s[a + 10], 16));
                        System.out.println("小型货车平均地点车速：" + xiaoxingsudu);
                        allEntity.setFintS2(xiaoxingsudu);
                        //大客车交通流量57,58
                        BigDecimal dake = BigDecimal.valueOf(Integer.parseInt(s[a + 12] + s[a + 11], 16));
                        System.out.println("大客车交通流量：" + dake);
                        allEntity.setFintV3(dake);
                        //大客车平均地点车速59
                        BigDecimal dakesudu = BigDecimal.valueOf(Integer.parseInt(s[a + 13], 16));
                        System.out.println("大客车平均地点车速：" + dakesudu);
                        allEntity.setFintS3(dakesudu);
                        //中型货车交通流量60,61
                        BigDecimal zhongxing = BigDecimal.valueOf(Integer.parseInt(s[a + 15] + s[a + 14], 16));
                        System.out.println("中型货车交通流量：" + zhongxing);
                        allEntity.setFintV4(zhongxing);
                        //中型货车平均地点车速62
                        BigDecimal zhongxingsudu = BigDecimal.valueOf(Integer.parseInt(s[a + 16], 16));
                        System.out.println("中型货车平均地点车速：" + zhongxingsudu);
                        allEntity.setFintS4(zhongxingsudu);
                        //大型货车交通流量63,64
                        BigDecimal daxing = BigDecimal.valueOf(Integer.parseInt(s[a + 18] + s[a + 17], 16));
                        System.out.println("大型货车交通流量：" + daxing);
                        allEntity.setFintV5(daxing);
                        //大型货车平均地点车速65
                        BigDecimal daxingsudu = BigDecimal.valueOf(Integer.parseInt(s[a + 19], 16));
                        System.out.println("大型货车平均地点车速：" + daxingsudu);
                        allEntity.setFintS5(daxingsudu);
                        //特大型货车交通流量66,67
                        BigDecimal teda = BigDecimal.valueOf(Integer.parseInt(s[a + 21] + s[a + 20], 16));
                        System.out.println("特大型货车交通流量：" + teda);
                        allEntity.setFintV6(teda);
                        //特大型货车平均地点车速68
                        BigDecimal tedasudu = BigDecimal.valueOf(Integer.parseInt(s[a + 22], 16));
                        System.out.println("特大型货车平均地点车速：" + tedasudu);
                        allEntity.setFintS6(tedasudu);
                        //集装箱车交通流量69,70
                        BigDecimal jizhuangxiang = BigDecimal.valueOf(Integer.parseInt(s[a + 24] + s[a + 23], 16));
                        System.out.println("集装箱车交通流量：" + jizhuangxiang);
                        allEntity.setFintV7(jizhuangxiang);
                        //集装箱车平均地点车速71
                        BigDecimal jizhuangxiangsudu = BigDecimal.valueOf(Integer.parseInt(s[a + 25], 16));
                        System.out.println("集装箱车平均地点车速：" + jizhuangxiangsudu);
                        allEntity.setFintS7(jizhuangxiangsudu);
                        //拖拉机交通流量72,73
                        BigDecimal tuolaji = BigDecimal.valueOf(Integer.parseInt(s[a + 27] + s[a + 26], 16));
                        System.out.println("拖拉机交通流量：" + tuolaji);
                        allEntity.setFintV8(tuolaji);
                        //拖拉机平均地点车速74
                        BigDecimal tuolajisudu = BigDecimal.valueOf(Integer.parseInt(s[a + 28], 16));
                        System.out.println("拖拉机平均地点车速：" + tuolajisudu);
                        allEntity.setFintS8(tuolajisudu);
                        //摩托车车交通流量75,76
                        BigDecimal motuoche = BigDecimal.valueOf(Integer.parseInt(s[a + 30] + s[a + 29], 16));
                        System.out.println("摩托车车交通流量：" + motuoche);
                        allEntity.setFintV9(motuoche);
                        //摩托车车平均地点车速77
                        BigDecimal motuochesudu = BigDecimal.valueOf(Integer.parseInt(s[a + 31], 16));
                        System.out.println("摩托车车平均地点车速：" + motuochesudu);
                        allEntity.setFintS9(motuochesudu);
                        hashMap.put(num, allEntity);
                    }

//                        String fstrDeviceid = "1";
                    //要发送的url 路径一定要对否则通不过
                    //String url = "http://127.0.0.1:9797/product/sdevloopgroup/findJiaodiao/" + fstrDeviceid;
                    String url = jiaodiaoUrl + fstrDeviceid;
                    this.getByfstrDeviceid(hashMap, url);

                    //CRC校验？？？规则未知
                    int[] crc = new int[]{Integer.parseInt(s[79 + (m - 1) * 32], 16),
                            Integer.parseInt(s[78 + (m - 1) * 32], 16)};
                    String substring1 = CRCUtil.crc16(crc).substring(0, 2).toUpperCase();
                    String substring2 = CRCUtil.crc16(crc).substring(2, 4).toUpperCase();

                    System.out.println("DSC 应答 RD 01 包(0x0A 包):" + "AA AA 05 00 0A " + s[43] + " " + s[44] + " FF FF " + substring1 + " " +
                            substring2 + " EE EE");

                    //DSC->RD
                    OutputStream out = clientConnectSocket.getOutputStream();//输出流
                    out.write(("AA AA 05 00 0A " + s[43] + " " + s[44] + " FF FF " + substring1 + " " +
                            substring2 + " EE EE").getBytes());

                } else {
                    System.out.println("等待接受数据");
                }
            }

        } catch (Exception e) {
            //错误
            System.out.println("error");
//                e.printStackTrace();
        }

    }


    /*@Override
    public void run() {
        while (true) {

            try {
                InputStream inputStream = clientConnectSocket.getInputStream();//获取客户端发送的流
                System.out.println("客户端传输的流：" + inputStream);
                SocketAddress remoteSocketAddress = clientConnectSocket.getRemoteSocketAddress();//远程主机地址
                System.out.println("远程主机地址：" + remoteSocketAddress);
                int port = clientConnectSocket.getPort();
                System.out.println("远程主机端口号：" + port);
                System.out.println("fstrDeviceid：" + fstrDeviceid);
                System.out.println("jiaodiaoUrl：" + jiaodiaoUrl);
                System.out.println("weiboUrl：" + weiboUrl);


                byte[] data = new byte[256];
                while (inputStream.read(data) != -1) {

                    //转为16进制
                    String message = ByteUtil.BinaryToHexString(data);
                    System.out.println("客户端传来消息: " + message);

                    //将传过来的数据根据" "进行分割为字符串数组
                    String[] s = message.split(" ");

                    int sum = 0;
                    //遍历数组，得到每一个字节，转为十进制进行求和计算
                    for (int i = 0; i < s.length; i++) {
                        sum += Integer.parseInt(s[i], 16);
                    }

                    //微波车辆检测器通信协议,直接将数据转为16进制进行对比
                    if ("57".equals(s[0]) && "31".equals(s[1]) && Integer.parseInt(s[3], 16) == 157) {
                        //终端→上位机
                        System.out.println("微波车辆检测器通信协议");

                        //报文长度
                        System.out.println("报文长度：" + Integer.parseInt(s[3], 16));
                        //设备编号
                        BigDecimal en = BigDecimal.valueOf(Integer.parseInt(s[4] + s[5], 16));
                        System.out.println("设备编号:" + en);
                        //读写标识
                        System.out.println("读写标识：" + Integer.parseInt(s[6], 16));
                        //周期起始时间
                        String time = (Integer.parseInt(s[7], 16) + 2000) + "-" + (Integer.parseInt(s[8], 16)) +
                                "-" + (Integer.parseInt(s[9], 16)) + " " + (Integer.parseInt(s[10], 16)) + ":" +
                                (Integer.parseInt(s[11], 16)) + ":" + (Integer.parseInt(s[12], 16));
                        System.out.println("周期起始时间(2000年为0):" + time);
                        //上报周期
                        BigDecimal rc = BigDecimal.valueOf(Integer.parseInt(s[13] + s[14], 16));

                        System.out.println("上报周期:" + rc);
                        //车道数
                        int num = Integer.parseInt(s[15], 16);
                        System.out.println("车道数：" + num);

                        //车道总流量,车道1型车流量,车道2型车流量,车道3型车流量
                        //车道4型车流量,车道5型车流量,车道占有率,车道平均车速
                        Map<Integer, RtJdloopgroupEntity> entityMap = total(s, num, time);

                        String makeChecksum = "";
                        for (int i = 0; i < 156; i++) {
                            makeChecksum += s[i];
                        }
                        String result = makeChecksum(makeChecksum);
                        //System.out.println("十六进制结果：" + result);
                        String substring = result.substring(result.length() - 2);
                        //System.out.println("十六进制低八位:" + substring);
                        int checkNum = Integer.parseInt(substring, 16);
                        System.out.println("十进制结果：" + checkNum);
                        //校验位
                        System.out.println("校验位：" + Integer.parseInt(s[156], 16));

                        //保证数据完整
                        if (Integer.parseInt(s[156], 16) == checkNum) {
                            System.out.println("数据正确，正在解析数据。。。");

                            //String fstrDeviceid = "1";
                            //要发送的url 路径一定要对否则通不过
                            //String url = "http://127.0.0.1:9797/product/sdevloopgroup/findWeiBo/" + fstrDevicei
                            // d;
                            String url = weiboUrl + fstrDeviceid;

                            this.getByfstrDeviceid(entityMap, url);

                            //上位机→终端
                            OutputStream out = clientConnectSocket.getOutputStream();//输出流
                            String resultCheck = makeChecksum(s[0] + s[1] + s[2] + "0A" + s[4] + s[5] + "010000");
                            out.write((s[0] + " " + s[1] + " " + s[2] + " 0A " + s[4] + " " + s[5] + " " + "01 00 00 " +
                                    resultCheck.substring(resultCheck.length() - 2)).getBytes());
                        } else {
                            System.out.println("数据发送不完整，请重新发送");
                        }
                    } else {
                        System.out.println("等待接受数据");
                    }
                }

            } catch (Exception e) {
                //错误
                System.out.println("error");
//                e.printStackTrace();
            }

        }
    }*/

    //激光交调，微波车辆检测器,根据fstrDeviceid查询车道的fstrLoopgroupid以及车道号FSTR_LANESECTID
    public void getByfstrDeviceid(Map<Integer, RtJdloopgroupEntity> hashMap, String url) throws IOException {

        // 创建默认的httpClient实例.
        HttpClient client = new DefaultHttpClient();
        // 创建httppost通过post方式访问
        HttpPost httppost = new HttpPost(url);


        // 创建参数队列
        //将数组对象转换为json数组
        JSONObject json = JSONObject.fromObject(hashMap);
//        JSONArray jsonArray = JSONArray.fromObject(hashMap);
        //将json数组转换为字符串
        String string = json.toString();
        //作为参数发送到controller
        StringEntity entity = new StringEntity(string, "utf-8");
        entity.setContentEncoding("UTF-8");
        entity.setContentType("application/json");
        httppost.setEntity(entity);

        HttpResponse response = client.execute(httppost);

       /* //获取接口的返回值
        InputStream in = response.getEntity().getContent();
        //得到数组
        byte[] getData = readInputStream(in);
        String s = String.valueOf(getData);
        System.out.println(s);*/

    }

    //读取返回的消息
    public static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

    //微波车辆检测器通信协议各车道数据
    public Map<Integer, RtJdloopgroupEntity> total(String[] s, int num, String time) {

        Map<Integer, RtJdloopgroupEntity> hashMap = new HashMap<>();
        for (int i = 1; i <= num; i++) {
            RtJdloopgroupEntity rtEntity = new RtJdloopgroupEntity();
            rtEntity.setFdtTime(time);
            rtEntity.setFstrLoopgroupid(String.valueOf(i));//临时设置的车道也就是假的id
            //车道总流量
            String total = String.valueOf(Integer.parseInt(s[16 + 14 * (i - 1)] + s[17 + 14 * (i - 1)], 16));
            rtEntity.setFstrValidity(total);
            System.out.println(i + "车道总流量:" + total);
            //车道1型车流量
            BigDecimal total_1 = BigDecimal.valueOf(Integer.parseInt(s[18 + 14 * (i - 1)] + s[19 + 14 * (i - 1)], 16));
            rtEntity.setFintV1(total_1);
            System.out.println(i + "车道1型车流量:" + total_1);
            //车道2型车流量
            BigDecimal total_2 = BigDecimal.valueOf(Integer.parseInt(s[20 + 14 * (i - 1)] + s[21 + 14 * (i - 1)], 16));
            rtEntity.setFintV2(total_2);
            System.out.println(i + "车道1型车流量:" + total_2);
            //车道3型车流量
            BigDecimal total_3 = BigDecimal.valueOf(Integer.parseInt(s[22 + 14 * (i - 1)] + s[23 + 14 * (i - 1)], 16));
            rtEntity.setFintV3(total_3);
            System.out.println(i + "车道1型车流量:" + total_3);
            //车道4型车流量
            BigDecimal total_4 = BigDecimal.valueOf(Integer.parseInt(s[24 + 14 * (i - 1)] + s[25 + 14 * (i - 1)], 16));
            rtEntity.setFintV4(total_4);
            System.out.println(i + "车道1型车流量:" + total_4);
            //车道5型车流量
            BigDecimal total_5 = BigDecimal.valueOf(Integer.parseInt(s[26 + 14 * (i - 1)] + s[27 + 14 * (i - 1)], 16));
            rtEntity.setFintV5(total_5);
            System.out.println(i + "车道1型车流量:" + total_5);
            //车道占有率
            BigDecimal occupy = BigDecimal.valueOf(Integer.parseInt(s[28 + 14 * (i - 1)], 16));
            rtEntity.setFintOccupy(occupy);
            System.out.println(i + "车道占有率:" + occupy);
            //车道平均车速
            BigDecimal speed = BigDecimal.valueOf(Integer.parseInt(s[29 + 14 * (i - 1)], 16));
            rtEntity.setFintSpeed(speed);
            System.out.println(i + "车道平均车速:" + speed);
            hashMap.put(i, rtEntity);
        }
        return hashMap;
    }

    /**
     * byte转为十进制int
     *
     * @param bytes
     * @return
     */
    public static int byte2int(byte bytes) {
        // 将byte转换为8位二进制字符串 依赖 commons-lang-x.x.jar包
        String binaryString = StringUtils.leftPad(Integer.toBinaryString(bytes & 0xff), 8, '0');
        // 将二进制字符串转换为十进制整数值
        int value = Integer.parseInt(binaryString, 2);
        return value;
    }

    /**
     * 两个十六进制转为十进制
     *
     * @param b1 十六进制低位
     * @param b2 十六进制高位
     * @return
     */
    public static int byteToInt(byte b1, byte b2) {
        int deci = (b1 | b2 << 8);
        return deci;

    }

    //十六进制求和
    public String makeChecksum(String hexdata) {
        if (hexdata == null || hexdata.equals("")) {
            return "00";
        }
        hexdata = hexdata.replaceAll(" ", "");
        int total = 0;
        int len = hexdata.length();
        if (len % 2 != 0) {
            return "00";
        }
        int num = 0;
        while (num < len) {
            String s = hexdata.substring(num, num + 2);
            total += Integer.parseInt(s, 16);
            num = num + 2;
        }
        return hexInt(total);
    }

    private String hexInt(int total) {
        int a = total / 256;
        int b = total % 256;
        if (a > 255) {
            return hexInt(a) + format(b);
        }
        return format(a) + format(b);
    }

    private String format(int hex) {
        String hexa = Integer.toHexString(hex);
        int len = hexa.length();
        if (len < 2) {
            hexa = "0" + hexa;
        }
        return hexa;
    }

    //十六进制转换为ASCII
    public String convertHexToString(String hex) {

        //ASCII
        StringBuilder sb = new StringBuilder();
        //十进制
        StringBuilder temp = new StringBuilder();

        for (int i = 0; i < hex.length() - 1; i += 2) {

            //grab the hex in pairs
            String output = hex.substring(i, (i + 2));
            //convert hex to decimal
            int decimal = Integer.parseInt(output, 16);

            //convert the decimal to character
            if (decimal == 0) {
                sb.append(0);
            } else {
                sb.append((char) decimal);
            }
            temp.append(decimal);
        }

        return sb.toString();
    }
}